<?php
/**
 * Created by PhpStorm.
 * User: shaowei
 * Date: 2019/1/23
 * Time: 上午10:34
 */

namespace App\Http\Model;


use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class UnionRank extends Base
{
    protected $table_union = "union"; //公会
    protected $table_rank = "union_rank"; //财富等级
    protected $table_active_rank = 'union_active_rank'; //活跃等级
    protected $table_sign_log = 'union_sign_log'; //签到表
    protected $table_union_donation = 'union_donation'; //捐赠表
    protected $table_union_contribution_log = 'union_contribution_log'; //贡献值日志表
    protected $table_union_user_contribution = 'union_user_contribution'; //用户贡献值表
    protected $table_union_bag = 'union_bag';
    protected $table_union_bag_log = 'union_bag_log';
    protected $table_union_privilege = 'union_privilege';
    protected $table_union_deposit_log = 'union_deposit_log';
    protected $table_union_deposit_check_log = 'union_deposit_check_log';

    protected $redis_wealth = 'UNION:WEALTH';
    protected $redis_wealth_level = 'UNION:WEALTH:LEVEL';

    protected $redis_active_wealth = 'UNION:ACTIVE:WEALTH';

    protected $redis_union_sign_log = 'UNION:SIGN:LOG:';
    protected $redis_union_donation_log = 'UNION:DONATION:LOG:';

    protected $redis_continue_sign_days = 'UNION:SIGN:DAYS:';
    protected $redis_continue_donation_days = 'UNION:DONATION:DAYS:';

    protected $redis_contribution_wealth = 'UNION:CONTRIBUTION:';

    protected $redis_consume_finish_user = 'UNION:CONSUME:FINISH:USER:'; //每日首次消费达标用户id

    protected $redis_union_exchange = 'UNION:SHOP:EXCHANGE:';

    public $toYesterdayStartTime;
    public $toYesterdayEndTime;

    public $toDayStartTime;
    public $toDayEndTime;

    public $toTomorrowStartTime;
    public $toTomorrowEndTime;

    public $sevenDayBeforeTime;
    public $thirtyDayBeforeTime;
    public $fifteenDayBeforeTime;

    public function __construct(array $attributes = [])
    {
        parent::__construct($this->table, $attributes);

        $this->toYesterdayStartTime = mktime(0, 0, 0, date('m'), date('d') - 1, date('Y'));
        $this->toYesterdayEndTime = mktime(0, 0, 0, date('m'), date('d') , date('Y')) -1;
        $this->toDayStartTime = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
        $this->toDayEndTime = mktime(0, 0, 0, date('m'), date('d') + 1, date('Y')) - 1;
        $this->toTomorrowStartTime = mktime(0, 0, 0, date('m'), date('d') + 1, date('Y'));
        $this->toTomorrowEndTime = mktime(0, 0, 0, date('m'), date('d') + 2, date('Y')) -1;
        $this->sevenDayBeforeTime = strtotime(date('Y-m-d 00:00:00', strtotime('-7 day')));
        $this->thirtyDayBeforeTime = date('Y-m-d 00:00:00', strtotime('-30 day'));
        $this->fifteenDayBeforeTime = strtotime(date('Y-m-d 00:00:00', strtotime('-15 day')));
    }

    /**
     * 获取等级列表
     */
    public function getRankList($type){
        $result = [];
        if($type != -1){
            switch ($type){
                case 1 :
                    $res = DB::table($this->table_rank)->orderBy('level','asc')->get();
                    $result = $this->objToArray($res);
                    break;
                case 2 :
                    $res = DB::table($this->table_active_rank)->orderBy('level','asc')->get();
                    $result = $this->objToArray($res);
                    break;
            }
            foreach ($result as &$v){
                if(isset($v['icon'])){
                    $v['icon'] = build_image($v['icon']);
                }
            }
        }else{
            $res1 =  DB::table($this->table_rank)->orderBy('level','asc')->get();
            $result1 = $this->objToArray($res1);
            foreach ($result1 as &$v){
                $v['icon'] = !empty($v['icon']) ? build_image($v['icon']) : '';
            }
            $res2 = DB::table($this->table_active_rank)->orderBy('level','asc')->get();
            $result2 = $this->objToArray($res2);
            foreach ($result2 as &$v){
                $v['icon'] = !empty($v['icon']) ? build_image($v['icon']) : '';
            }
            $result['rank'] = $result1;
            $result['active_rank'] = $result2;
        }
        return $result;
    }

    public function setWealth($data){
        Redis::HMSET($this->redis_wealth ,$data);
    }
    public function setWealthLevel($data){
        Redis::HMSET($this->redis_wealth_level ,$data);
    }
    public function getWealth($union_id){
        $wealth = Redis::HGET($this->redis_wealth,$union_id);
        return empty($wealth) ? 0 : $wealth;
    }
    public function getWealthLevel($union_id){
        $level = Redis::HGET($this->redis_wealth_level,$union_id);
        return empty($level) ? 1 : $level;
    }
    //设置活跃等级的值
    public function setActiveWealth(){
        //删除昨日消费达标用户id
        Redis::del($this->redis_consume_finish_user.date('Ymd' ,strtotime('-1 day')));
        //删除昨日产生贡献值的缓存数据
        Redis::del($this->redis_contribution_wealth.date('Ymd' ,strtotime('-1 day')));
        $res = DB::table($this->table_union_contribution_log)
            ->leftJoin('union' ,'union.id','=','union_contribution_log.union_id')
            ->where([
                ['union_contribution_log.value' ,'>',0] ,
                ['union_contribution_log.created_time', '>=', $this->thirtyDayBeforeTime],
                ['union_contribution_log.created_time', '<=', date('Y-m-d H:i:s' ,$this->toDayEndTime)],
                ['union.id' ,'>' ,0]
            ])
            ->select('union_contribution_log.union_id', DB::raw('SUM(value) as value'))
            ->groupBy('union_contribution_log.union_id')
            ->get();
        $res = $this->objToArray($res);
        $data = !empty($res) ? array_column($res ,'value' ,'union_id') : [];
        if(!empty($data)){
            Redis::HMSET($this->redis_active_wealth ,$data);
        }
    }
    //获取活跃等级值
    public function getActiveWealth($union_id){
        $data =  Redis::HGET($this->redis_active_wealth ,$union_id) ?? [];
        return empty($data) ? 0 : $data;
    }

    /**根据用户id获取今日签到信息
     * @param $union_id
     * @param $user_id
     * @return mixed
     */
    public function getTodaySignData($union_id,$user_id){
        $sign_info = Redis::HGET($this->redis_union_sign_log.date('Ymd').":".$union_id ,$user_id);
        return empty($sign_info) ? false : true;
    }

    /**获取公会签到全部信息
     * @param $union_id
     * @return array
     */
    public function getTodayTotalSignData($union_id){
        $today_sign = Redis::HKEYS($this->redis_union_sign_log.date('Ymd').":".$union_id);
        arsort($today_sign);
        return empty($today_sign) ? [] : $today_sign;
    }

    /**根据用户id查询昨天签到信息
     * @param $union_id
     * @param $userId
     * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Query\Builder|mixed|object|null
     */
    public function getYesterdaySignData($union_id ,$userId)
    {
        $yesterday_sign = Redis::HGET($this->redis_union_sign_log.date('Ymd' ,$this->toYesterdayStartTime).":".$union_id ,$userId);
        return empty($yesterday_sign) ? false : true;
    }

    /**查询昨天签到全部信息
     * @param $union_id
     * @return array
     */
    public function getYesterdayTotalSignData($union_id)
    {
        $yesterday_sign = Redis::HKEYS($this->redis_union_sign_log.date('Ymd' ,$this->toYesterdayStartTime).":".$union_id);
        return empty($yesterday_sign) ? [] : $yesterday_sign;
    }
    /**
     * 签到
     *
     * @param int $userId 用户ID
     * @return bool
     */
    public function createSignLog($union_id ,$user_id)
    {
        $res = DB::table($this->table_sign_log)->insertGetId(['union_id' => $union_id ,'user_id' => $user_id, 'created_at' => time()]);
        if($res){
            Redis::HSET($this->redis_union_sign_log.date('Ymd').":".$union_id ,$user_id ,time());
            //设置次日23:59:59过期
            Redis::EXPIRE($this->redis_union_sign_log.date('Ymd').":".$union_id , $this->toTomorrowEndTime - time());
        }
        return $res;
    }

    /**设置用户连续签到天数
     * @param $union_id
     * @param $user_id
     * @param $times
     */
    public function setContinueSignDays($union_id ,$user_id,$times){
        Redis::HSET($this->redis_continue_sign_days.$union_id ,$user_id ,$times);
    }

    /**获取用户连续签到天数
     * @param $union_id
     * @param $user_id
     * @return int
     */
    public function getContinueSignDays($union_id,$user_id){
        $days = Redis::HGET($this->redis_continue_sign_days.$union_id ,$user_id);
        return empty($days) ? 0 : $days;
    }

    /**设置用户连续捐赠天数
     * @param $union_id
     * @param $user_id
     * @param $times
     */
    public function setContinueDonationDays($union_id ,$user_id,$times){
        Redis::HSET($this->redis_continue_donation_days.$union_id ,$user_id ,$times);
    }

    /**获取连续续捐赠天数
     * @param $union_id
     * @param $user_id
     * @return int
     */
    public function getContinueDonationDays($union_id,$user_id){
        $days = Redis::HGET($this->redis_continue_donation_days.$union_id ,$user_id);
        return empty($days) ? 0 : $days;
    }

    //增加用户的贡献值
    public function incUserContribution($union_id, $user_id ,$val)
    {
        $time = time();
        $sql = "insert into zb_{$this->table_union_user_contribution} (`union_id`,`user_id`,`value`,`change_time`) values ({$union_id},{$user_id} ,{$val} ,{$time}) on duplicate key update value = value+{$val} ,change_time= {$time}";
        return DB::INSERT($sql);
    }

    /**贡献值日志
     * @param $union_id 公会id
     * @param $user_id 用户id
     * @param $value 贡献值 负数表示扣除
     * @param $type 1 签到 2捐赠 3 消费 4兑换礼物
     * @param $desc 描述
     * @return int
     */
    public function addContributionLog($union_id, $user_id ,$value,$type,$desc,$is_update=1){
        $data = array(
            'union_id'=>$union_id,
            'user_id'=>$user_id ,
            'type' =>$type ,
            'value'=>$value,
            'desc'=>$desc
        );
        $res = DB::table($this->table_union_contribution_log)->insertGetId($data);
        if($res && $is_update==1){
            $wealth = Redis::ZSCORE($this->redis_contribution_wealth.date('Ymd') ,$union_id) ?? 0;
            Redis::ZADD($this->redis_contribution_wealth.date('Ymd') ,$value+$wealth ,$union_id);
        }
    }

    /**记录每日首次房间消费超过500钻石的用户
     * @param $data
     */
    public function setTodayConsumeFinishUser($data){
        Redis::HMSET($this->redis_consume_finish_user.date('Ymd') ,$data);
    }

    /**获取每日首次房间消费超过500钻石的用户
     * @return mixed
     */
    public function getTodayConsumeFinishUser(){
        return Redis::HKEYS($this->redis_consume_finish_user.date('Ymd'));
    }
    /**根据财富等级计算贡献值
     * @param $level
     * @return int
     */
    public function getContributionByRank($level){
        $value = 10;
        if($level >= 15){
            $value = 20;
        }else if($level >= 10){
            $value = 15;
        }else if($level >= 5){
            $value = 12;
        }
        return $value;
    }

    /**根据用户id判断今日是否已捐赠
     * @param $union_id
     * @param $user_id
     * @return bool
     */
    public function getTodayDonation($union_id ,$user_id){
        $donation_info = Redis::HGET($this->redis_union_donation_log.date('Ymd').":".$union_id ,$user_id);
        return empty($donation_info) ? false : true;
    }

    /**获取今日总捐赠数据
     * @param $union_id
     * @param $user_id
     * @return array
     */
    public function getTodayTotalDonation($union_id){
        $donation_info = Redis::HKEYS($this->redis_union_donation_log.date('Ymd').":".$union_id);
        return empty($donation_info) ? [] : $donation_info;
    }

    /**捐献
     * @param $union_id
     * @param $user_id
     * @return int
     */
    public function createDonation($union_id ,$user_id)
    {
        $res = DB::table($this->table_union_donation)->insertGetId(['union_id' => $union_id ,'user_id' => $user_id, 'created_at' => time()]);
        if($res){
            Redis::HSET($this->redis_union_donation_log.date('Ymd').":".$union_id ,$user_id ,time());
            //设置次日23:59:59过期
            Redis::EXPIRE($this->redis_union_donation_log.date('Ymd').":".$union_id , $this->toTomorrowEndTime - time());
        }
        return $res;
    }
    /**根据用户id 查询昨天签捐赠数据
     * @param $union_id
     * @param $userId
     * @return bool
     */
    public function getYesterdayDonationData($union_id ,$userId)
    {
        $yesterday_donation = Redis::HGET($this->redis_union_donation_log.date('Ymd' ,$this->toYesterdayStartTime).":".$union_id ,$userId);
        return empty($yesterday_donation) ? false : true;
    }

    /**查询昨日捐赠总数据
     * @param $union_id
     * @return array
     */
    public function getYesterdayTotalDonationData($union_id)
    {
        $yesterday_donation = Redis::HKEYS($this->redis_union_donation_log.date('Ymd' ,$this->toYesterdayStartTime).":".$union_id);
        return empty($yesterday_donation) ? [] : $yesterday_donation;
    }

    /**获取签到列表
     * @param $union_id
     * @return array|mixed
     */
    public function getSignList($union_id){
        $res = DB::table($this->table_sign_log)
            ->where([
                ['union_id' ,$union_id] ,
                ['created_at', '>=', $this->toDayStartTime],
                ['created_at', '<=', $this->toDayEndTime]
            ])
            ->orderBy('created_at', 'desc')
            ->get();
        $data = $this->objToArray($res);
        return empty($data) ? [] : $data;
    }
    /**获取捐赠列表
     * @param $union_id
     * @return array|mixed
     */
    public function getDonationList($union_id){
        $res = DB::table($this->table_union_donation)
            ->where([
                ['union_id' ,$union_id] ,
                ['created_at', '>=', $this->toDayStartTime],
                ['created_at', '<=', $this->toDayEndTime]
                ])
            ->orderBy('created_at', 'desc')
            ->get();
        $data = $this->objToArray($res);
        return empty($data) ? [] : $data;
    }

    /**统计公会贡献值
     * @param int $is_new
     * @return array
     */
    public function getContributionRank($is_new = 0,$page,$pageSize){
        $where[] = ['stop', '=', '1'];
        if($is_new ==1){
            $where[] = ['created_at', '>=', date('Y-m-d H:i:s',$this->fifteenDayBeforeTime)];
            $union_list = DB::table($this->table_union)->where($where)->get();
            $union_list = $this->objToArray($union_list);
            foreach ($union_list as $u_l){
                $union_contribution = Redis::HGET($this->redis_active_wealth,$u_l['union_id']);
                if(!empty($union_contribution)){
                    $u_l['value'] = $union_contribution;
                }else{
                    $u_l['value'] = 0;
                }
            }
            $orderByList = array_column($union_list, 'value');
            array_multisort($orderByList, SORT_DESC, $union_list);
            return $union_list;
        }else{
            $key = $this->redis_contribution_wealth.date('Ymd');
            if(!Redis::EXISTS($key)){
                $this->setTodayUnionInfoToRedis();
            }
            $data = Redis::zrevrange($key, $page * $pageSize, $page * $pageSize + $pageSize-1);
            return $data;
        }
    }

    /**解散公会删除贡献值，活跃值，财富值，财富等级
     * @param $union_id
     */
    public function delContribution($union_id){
        Redis::zrem($this->redis_contribution_wealth.date('Ymd') ,$union_id);
        Redis::HDEL($this->redis_active_wealth ,$union_id);
        Redis::HDEL($this->redis_wealth ,$union_id);
        Redis::HDEL($this->redis_wealth_level ,$union_id);
    }
    /**设置公会押金
     * @param $union_id
     * @param $user_id
     * @param $deposit
     * @param $type
     * @return int
     */
    public function incDeposit($union_id ,$user_id ,$deposit,$type,$status=0){
        DB::table($this->table_union)
            ->where(['id'=>$union_id])
            ->increment('deposit',$deposit);
        $union = DB::table($this->table_union)
            ->where('id', $union_id)
            ->first(['deposit']);
        $deposit_log = [
            "union_id" => $union_id,
            "user_id" => $user_id,
            "type" => $type,
            'status'=>$status,
            "diamond_value" => $deposit,
            'remain_diamond' =>$union->deposit
        ];
        return DB::table($this->table_union_deposit_log)->insertGetId($deposit_log);
    }

    /**后台提取记录表
     * @param $union_id
     * @param $user_id
     * @param $deposit
     * @param $check_id
     * @param $opt_id
     * @param $status
     * @return bool
     */
    public function addDepositCheckLog($union_id ,$user_id ,$deposit,$check_id,$opt_id,$status){
        $deposit_log = [
            "union_id" => $union_id,
            "user_id" => $user_id,
            "check_id" => $check_id,
            "opt_id" => $opt_id,
            "status" => $status,
            "diamond_value" => $deposit
        ];
        return DB::table($this->table_union_deposit_check_log)->insert($deposit_log);
    }

    /**撤回押金提取
     * @param $union_id
     * @param $deposit
     * @param int $status
     * @param $log_id
     */
    public function recallDrawDeposit($union_id ,$deposit ,$log_id ,$status){
        DB::table($this->table_union)
            ->where(['id'=>$union_id])
            ->increment('deposit',$deposit);
        $union = DB::table($this->table_union)
            ->where('id', $union_id)
            ->first(['deposit']);
        DB::table($this->table_union_deposit_log)->where('id',$log_id)->update(array('status'=>$status,'remain_diamond'=>$union->deposit));
    }

    /**获取押金日志
     * @param $id
     * @return mixed
     */
    public function getDepositLog($id){
        $data = DB::table($this->table_union_deposit_log)->find($id);
        return $this->objToArray($data);
    }

    /**更新公会押金状态
     * @param $id
     * @param $status
     * @return int
     */
    public function updateDepositLogStatus($id,$status){
        return DB::table($this->table_union_deposit_log)
            ->where('id' ,$id)
            ->update(array('status'=>$status ,'change_time'=>time()));
    }

    /**获取自己的贡献值
     * @param $union_id
     * @param $user_id
     * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Query\Builder|object|null
     */
    public function getMyContribution($union_id ,$user_id){
        return DB::table($this->table_union_user_contribution)
            ->where(['union_id'=>$union_id ,'user_id' =>$user_id])
            ->first();
    }

    /**获取公会商城刷新时间
     * @return float|int
     */
    public function getShopRefreshTime(){
        return mktime(23, 59, 59, date('m'), date('t'), date('Y'));
    }

    /**根据活跃值获取活跃等级
     * @param $total
     * @return mixed
     */
    public function getActiveRank($total)
    {
        $res = DB::table($this->table_active_rank)
            ->where('start_value','<=',$total)
            ->where('end_value' ,'>=' ,$total)
            ->first();
        return $this->objToArray($res);
    }

    public function getBagList(){
        $res = DB::table($this->table_union_bag)
            ->leftJoin('prop' ,'prop.prop_id','=','union_bag.prop_id')
            ->orderBy('level','asc')
            ->get();
        $data = $this->objToArray($res);
        foreach ($data as &$r){
            $r['data_image'] = build_image($r['data_image']);
        }
        return $data;
    }

    /**获取礼包信息
     * @param $shop_id
     * @return mixed
     */
    public function getBagById($bag_id){
        $res = DB::table($this->table_union_bag)->where('id',$bag_id)->first();
        return  $this->objToArray($res);
    }

    /**添加领取礼包记录
     * @param $union_id
     * @param $user_id
     * @param $bag_id
     * @param $prop_id
     * @param $level
     * @return int
     */
    public function addBagReceiveLog($union_id,$user_id,$bag_id,$prop_id,$level){
        $data = array(
            'union_id' =>$union_id,
            'bag_id' =>$bag_id,
            'user_id' =>$user_id,
            'prop_id' =>$prop_id,
            'level' =>$level
        );
        return DB::table($this->table_union_bag_log)->insertGetId($data);
    }

    /**获取领取礼包的记录
     * @param $user_id
     * @param $level
     * @return mixed
     */
    public function getReceiveBagLog($user_id ,$bag_id = 0){
        $where['user_id'] = $user_id;
        if(!empty($bag_id)){
            $where['bag_id'] = $bag_id;
            $res = DB::table($this->table_union_bag_log)
                ->where($where)
                ->first();
        }else{
            $res = DB::table($this->table_union_bag_log)
                ->where($where)
                ->get();
        }
        return $this->objToArray($res);
    }

    /**获取公会特权
     * @return mixed
     */
    public function getPrivilege(){
        $res = DB::table($this->table_union_privilege)
            ->orderBy('level','asc')
            ->get();
        $data = $this->objToArray($res);
        foreach ($data as &$val){
            $val['high_image'] = build_image($val['high_image']);
            $val['murky_image'] = build_image($val['murky_image']);
            $val['auth_desc'] = "资质认证金额达".($val['start_value']/10000).'万钻石';
            $val['finance_desc'] = $val['level'] >0 ? '公会财富等级达Lv'.$val['level'] : '';
        }
        return $data;
    }

    /**获取未处理且申请时间大于15的押金提取记录
     * 修改 7天
     * @return mixed
     */
    public function getNoSettleDeposit(){
        $res = DB::table($this->table_union_deposit_log)
            ->where('type' ,2)
            ->where('status' ,1)
            ->where('created_time','<=',date('Y-m-d H:i:s' ,strtotime('-7 day')))
            ->get();
        return $this->objToArray($res);
    }

    public function getListByActiveRank($page ,$pageSize){
        $key = $this->redis_contribution_wealth.date('Ymd');
        if(!Redis::EXISTS($key)){
            $this->setTodayUnionInfoToRedis();
        }
        $keys = Redis::zrevrange($key, $page * $pageSize, $page * $pageSize + $pageSize-1);

        $unions = DB::table($this->table_union)
            ->whereIn('id',$keys)
            ->where('authentication_status','>=',1)
            ->get();
        $unions = $this->objToArray($unions);
        return $unions;
    }

    public function incrbyShopExchangeNum($shop_id,$val=0){
        $ym = date('Y').date('m');
        Redis::HINCRBY($this->redis_union_exchange.$ym ,$shop_id,$val);
    }

    public function getShopExchangeNum($shop_id){
        $ym = date('Y').date('m');
        return Redis::HGET($this->redis_union_exchange.$ym ,$shop_id) ?? 0;
    }

    /**
     * 每日零点定时更新公会信息到redis
     */
    public function setTodayUnionInfoToRedis(){
        $res = DB::table($this->table_union)
            ->orderBy('id' ,'asc')
            ->get(['id']);
        $res = $this->objToArray($res);
        foreach ($res as $r){
            Redis::ZADD($this->redis_contribution_wealth.date('Ymd') ,0,$r['id']);
        }
    }

    /**创建公会时设置贡献值为0
     * @param $union_id
     */
    public function setContribution($union_id){
        Redis::ZADD($this->redis_contribution_wealth.date('Ymd') ,0,$union_id);
    }

    /**押金日志
     * @param $union_id
     * @param $user_id
     * @param $type
     * @param $status
     * @param $deposit
     * @param $remain_diamond
     * @return int
     */
    public function addDepositLog($union_id,$user_id,$type,$status,$deposit,$remain_diamond){
        $deposit_log = [
            "union_id" => $union_id,
            "user_id" => $user_id,
            "type" => $type,
            'status'=>$status,
            "diamond_value" => $deposit,
            'remain_diamond' =>$remain_diamond
        ];
        return DB::table($this->table_union_deposit_log)->insertGetId($deposit_log);
    }
}